"""
视频数据库管理CLI命令

提供视频数据库的查询、统计和管理功能。
"""

import click
from typing import Optional

from src.core.di import injector
from src.services.material_workflow_database_service import MaterialWorkflowDatabaseService
from src.repositories.video_repository import VideoRepository
from src.cli.utils import run_async


@click.group()
def video_db():
    """视频数据库管理命令"""
    pass


@video_db.command()
def stats():
    """显示视频数据库统计信息"""
    try:
        db_service = injector.get(MaterialWorkflowDatabaseService)
        stats = db_service.get_workflow_statistics()
        
        click.echo(f"\n📊 视频数据库统计信息:")
        click.echo(f"   总视频数: {stats['total_videos']} 个")
        click.echo(f"   已处理视频: {stats['processed_videos']} 个")
        
        # 分类分布
        classification_dist = stats.get('classification_distribution', {})
        if classification_dist:
            click.echo(f"\n🏷️  分类分布:")
            for category, count in classification_dist.items():
                click.echo(f"     {category}: {count} 个")
        
        # 最近视频
        recent_videos = stats.get('recent_videos', [])
        if recent_videos:
            click.echo(f"\n📹 最近处理的视频:")
            for video in recent_videos[:5]:  # 只显示前5个
                duration = video.get('duration', 0)
                duration_str = f"{duration:.1f}s" if duration else "N/A"
                click.echo(f"     - {video['file_name']} ({duration_str})")
        
    except Exception as e:
        click.echo(f"❌ 获取统计信息失败: {e}")


@video_db.command()
@click.option('--limit', '-l', type=int, default=20, help='限制结果数量')
@click.option('--category', '-c', help='按分类筛选')
@click.option('--min-duration', type=float, help='最小时长(秒)')
@click.option('--max-duration', type=float, help='最大时长(秒)')
@click.option('--processed-only', is_flag=True, help='只显示已处理的视频')
def list_videos(limit: int, category: Optional[str], min_duration: Optional[float], 
               max_duration: Optional[float], processed_only: bool):
    """列出视频"""
    try:
        video_repo = injector.get(VideoRepository)
        
        # 构建查询条件
        filters = {}
        if processed_only:
            filters['is_processed'] = True
        
        # 按时长筛选
        if min_duration is not None or max_duration is not None:
            videos = video_repo.find_by_duration_range(min_duration, max_duration)
        else:
            videos = video_repo.find(filters=filters, limit=limit, order_by="created_at", order_desc=True)
        
        if not videos:
            click.echo("❌ 未找到符合条件的视频")
            return
        
        # 如果指定了分类，需要进一步筛选
        if category:
            filtered_videos = []
            for video in videos:
                video_with_classifications = video_repo.get_with_classifications(video.id)
                if video_with_classifications and video_with_classifications.classifications:
                    for cls in video_with_classifications.classifications:
                        if cls.category == category:
                            filtered_videos.append(video)
                            break
            videos = filtered_videos
        
        click.echo(f"\n📹 视频列表 (显示前 {min(len(videos), limit)} 个):")
        click.echo("-" * 120)
        click.echo(f"{'文件名':<30} {'时长':<8} {'尺寸':<12} {'大小':<10} {'状态':<8} {'分类':<15} {'创建时间':<20}")
        click.echo("-" * 120)
        
        for video in videos[:limit]:
            # 获取分类信息
            video_with_cls = video_repo.get_with_classifications(video.id)
            categories = []
            if video_with_cls and video_with_cls.classifications:
                categories = [cls.category for cls in video_with_cls.classifications]
            
            # 格式化显示
            file_name = video.file_name[:28] + '...' if len(video.file_name) > 30 else video.file_name
            duration_str = f"{video.duration:.1f}s" if video.duration else "N/A"
            size_str = f"{video.width}x{video.height}" if video.width and video.height else "N/A"
            file_size_mb = video.file_size / (1024 * 1024) if video.file_size else 0
            file_size_str = f"{file_size_mb:.1f}MB" if file_size_mb > 0 else "N/A"
            status = "已处理" if video.is_processed else "未处理"
            category_str = ",".join(categories[:2])  # 最多显示2个分类
            if len(category_str) > 13:
                category_str = category_str[:10] + "..."
            created_str = video.created_at.strftime('%Y-%m-%d %H:%M') if video.created_at else "N/A"
            
            click.echo(f"{file_name:<30} {duration_str:<8} {size_str:<12} {file_size_str:<10} {status:<8} {category_str:<15} {created_str:<20}")
        
        if len(videos) > limit:
            click.echo(f"\n💡 还有 {len(videos) - limit} 个视频，使用 --limit 参数查看更多")
        
    except Exception as e:
        click.echo(f"❌ 列出视频失败: {e}")


@video_db.command()
@click.argument('video_id', type=int)
def info(video_id: int):
    """显示视频详细信息"""
    try:
        video_repo = injector.get(VideoRepository)
        video = video_repo.get_with_all_relations(video_id)
        
        if not video:
            click.echo(f"❌ 未找到ID为 {video_id} 的视频")
            return
        
        click.echo(f"\n📹 视频详细信息:")
        click.echo(f"   ID: {video.id}")
        click.echo(f"   文件名: {video.file_name}")
        click.echo(f"   文件路径: {video.file_path}")
        click.echo(f"   文件大小: {video.file_size / (1024 * 1024):.1f} MB")
        click.echo(f"   文件哈希: {video.file_hash or 'N/A'}")
        
        # 视频属性
        click.echo(f"\n🎬 视频属性:")
        click.echo(f"   时长: {video.duration:.1f} 秒" if video.duration else "   时长: N/A")
        click.echo(f"   分辨率: {video.width}x{video.height}" if video.width and video.height else "   分辨率: N/A")
        click.echo(f"   帧率: {video.fps} fps" if video.fps else "   帧率: N/A")
        click.echo(f"   比特率: {video.bitrate} bps" if video.bitrate else "   比特率: N/A")
        click.echo(f"   编码: {video.codec or 'N/A'}")
        click.echo(f"   格式: {video.format or 'N/A'}")
        
        # 状态信息
        click.echo(f"\n📊 状态信息:")
        click.echo(f"   已处理: {'是' if video.is_processed else '否'}")
        click.echo(f"   可用: {'是' if video.is_available else '否'}")
        click.echo(f"   最后访问: {video.last_accessed.strftime('%Y-%m-%d %H:%M:%S') if video.last_accessed else 'N/A'}")
        click.echo(f"   创建时间: {video.created_at.strftime('%Y-%m-%d %H:%M:%S') if video.created_at else 'N/A'}")
        click.echo(f"   更新时间: {video.updated_at.strftime('%Y-%m-%d %H:%M:%S') if video.updated_at else 'N/A'}")
        
        # 分类信息
        if video.classifications:
            click.echo(f"\n🏷️  分类信息 ({len(video.classifications)} 个):")
            for cls in video.classifications:
                click.echo(f"     分类: {cls.category}")
                click.echo(f"     置信度: {cls.confidence:.2f}")
                click.echo(f"     分类器: {cls.classifier_type}")
                click.echo(f"     模型: {cls.model_name or 'N/A'}")
                if cls.reasoning:
                    reasoning = cls.reasoning[:100] + '...' if len(cls.reasoning) > 100 else cls.reasoning
                    click.echo(f"     推理: {reasoning}")
                click.echo(f"     处理时间: {cls.processing_time:.2f}s" if cls.processing_time else "     处理时间: N/A")
                click.echo(f"     创建时间: {cls.created_at.strftime('%Y-%m-%d %H:%M:%S') if cls.created_at else 'N/A'}")
                click.echo()
        
        # 元数据信息
        if video.video_metadata:
            click.echo(f"📋 元数据信息:")
            click.echo(f"   创建时间: {video.video_metadata.created_at.strftime('%Y-%m-%d %H:%M:%S') if video.video_metadata.created_at else 'N/A'}")
            click.echo(f"   更新时间: {video.video_metadata.updated_at.strftime('%Y-%m-%d %H:%M:%S') if video.video_metadata.updated_at else 'N/A'}")
            
            # 显示原始元数据的摘要
            if video.video_metadata.raw_metadata:
                import json
                try:
                    metadata = json.loads(video.video_metadata.raw_metadata)
                    click.echo(f"   原始元数据字段: {len(metadata)} 个")
                except:
                    click.echo(f"   原始元数据: 解析失败")
        
    except Exception as e:
        click.echo(f"❌ 获取视频信息失败: {e}")


@video_db.command()
@click.option('--category', '-c', help='按分类筛选')
@click.option('--min-confidence', type=float, help='最小置信度')
def list_classifications(category: Optional[str], min_confidence: Optional[float]):
    """列出分类信息"""
    try:
        video_repo = injector.get(VideoRepository)
        
        # 获取所有视频的分类信息
        videos = video_repo.find(limit=1000)  # 限制查询数量
        
        all_classifications = []
        for video in videos:
            video_with_cls = video_repo.get_with_classifications(video.id)
            if video_with_cls and video_with_cls.classifications:
                for cls in video_with_cls.classifications:
                    # 应用筛选条件
                    if category and cls.category != category:
                        continue
                    if min_confidence and cls.confidence < min_confidence:
                        continue
                    
                    all_classifications.append({
                        'video_id': video.id,
                        'video_name': video.file_name,
                        'classification': cls
                    })
        
        if not all_classifications:
            click.echo("❌ 未找到符合条件的分类")
            return
        
        click.echo(f"\n🏷️  分类列表 ({len(all_classifications)} 个):")
        click.echo("-" * 100)
        click.echo(f"{'视频名称':<30} {'分类':<15} {'置信度':<8} {'分类器':<12} {'创建时间':<20}")
        click.echo("-" * 100)
        
        for item in all_classifications[:50]:  # 只显示前50个
            cls = item['classification']
            video_name = item['video_name'][:28] + '...' if len(item['video_name']) > 30 else item['video_name']
            created_str = cls.created_at.strftime('%Y-%m-%d %H:%M') if cls.created_at else "N/A"
            
            click.echo(f"{video_name:<30} {cls.category:<15} {cls.confidence:<8.2f} {cls.classifier_type:<12} {created_str:<20}")
        
        if len(all_classifications) > 50:
            click.echo(f"\n💡 还有 {len(all_classifications) - 50} 个分类，使用筛选条件查看更多")
        
    except Exception as e:
        click.echo(f"❌ 列出分类失败: {e}")


@video_db.command()
@click.confirmation_option(prompt='确定要清理孤立记录吗？')
def cleanup():
    """清理孤立的元数据和分类记录"""
    try:
        video_repo = injector.get(VideoRepository)
        
        click.echo("🧹 开始清理孤立记录...")
        
        # 清理孤立的元数据
        orphaned_metadata = video_repo.cleanup_orphaned_metadata()
        click.echo(f"   清理孤立元数据: {orphaned_metadata} 个")
        
        # 清理孤立的分类
        orphaned_classifications = video_repo.cleanup_orphaned_classifications()
        click.echo(f"   清理孤立分类: {orphaned_classifications} 个")
        
        click.echo("✅ 清理完成")
        
    except Exception as e:
        click.echo(f"❌ 清理失败: {e}")


if __name__ == '__main__':
    video_db()
